package com.jfinal.web.controller;

import com.alibaba.fastjson.JSON;
import com.jfinal.aop.Enhancer;
import com.jfinal.kit.ReflectKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.LogicModel;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.QueryObject;
import com.jfinal.plugin.activerecord.sql.Cnd;
import com.jfinal.plugin.activerecord.sql.Spec;
import com.jfinal.service.BaseService;
import com.jfinal.service.Service;

import java.lang.reflect.Type;

public abstract class DefaultController<M extends Model<M>> extends BaseController {

    protected Class<M> modelClass;
    protected BaseService<M> service;

    @SuppressWarnings("unchecked")
    public DefaultController() {
        Type type = ReflectKit.getParameterizedTypes(this)[0];
        try {
            this.modelClass = (Class<M>) ReflectKit.getClass(type);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        service = Enhancer.enhance(Service.get(modelClass));
    }

    /**
     * 获取model参数
     *
     * @return
     */
    protected M getModel() {
        String requestBody = getRequestBody();
        if (StrKit.notBlank(requestBody) && requestBody.trim().startsWith("{")) {
            M model = JSON.parseObject(requestBody, modelClass);
            return model;
        }
        return getModel(modelClass, "", true);
    }

    public void index() {
        keepPara();
    }

    /**
     * 查询
     */
    public void list() {
        Spec spec = customSearch(getQueryObject());
        renderJson(service.paginate(spec));
        return;
    }

    /**
     * 自定义查询
     *
     * @param query
     * @return
     */
    protected Spec customSearch(QueryObject query) {
        Spec spec = query.toSpec();

        //过滤已标记删除的字段
        if (getModel() instanceof LogicModel) {
            spec.and(LogicModel.DELETED, Cnd.EQ, false);
        }

        //首先按sort值排序
        if (!StrKit.isBlank(query.getSort())) {
            spec.orderBy(query.getSort(), query.getOrder());
        }

        return spec;
    }

    /**
     * 查看
     */
    public void get() {
        Object id = getPara("id");
        if (id == null) {
            renderFailed("id can’t be null !");
            return;
        }
        Spec spec = Spec.where("id=?", id);
        if (getModel() instanceof LogicModel) {
            spec.and(LogicModel.DELETED, Cnd.EQ, false);
        }
        spec = beforeGet(spec);
        M item = service.findFirstBy(spec);
        if (item == null) {
            renderFailed("item not exists, id=" + id);
        } else {
            beforeRender(item);
            renderSuccess(item);
        }

    }

    protected Spec beforeGet(Spec spec) {
        return spec;
    }

    /**
     * 获取对象之后
     *
     * @param model
     */
    protected void beforeRender(M model) {

    }
}
